package cn.csc.module.pay.mq.consumer;

import cn.csc.framework.common.constants.GlobalConstant;
import cn.csc.framework.common.util.json.JsonUtils;
import cn.csc.module.pay.dal.dataobject.notify.NotifyRefundLogDO;
import cn.csc.module.pay.dal.dataobject.notify.PayNotifyTaskDO;
import cn.csc.module.pay.enums.notify.PayNotifyStatusEnum;
import cn.csc.module.pay.service.notify.NotifyRefundLogService;
import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.messaging.Message;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * @Author：云隐
 * @Date：2023/3/20 14:24
 */
@Slf4j
@Component
public class RefundOrderConsumer {

    @Resource
    private NotifyRefundLogService notifyRefundLogService;

    @Resource
    @Lazy // 循环依赖（自己依赖自己），避免报错
    private RefundOrderConsumer refundOrderConsumer;

    @Bean
    public Consumer<Message<String>> refundOrder() {
        return message -> {
            try {
                Map<String, Object> m = JsonUtils.parseObject(message.getPayload(), Map.class);
                refundOrderConsumer.executeNotifyAsync(m);
            } catch (Exception e) {
                log.error("----[refundOrder消息消费]调用退款订单回调本地通知消息失败:{}", message, e);
            }
        };
    }

    /**
     * @Async默认使用的ForkJoinPool.commonPool
     */
    @Async("defaultTaskExecutor")
    public void executeNotifyAsync(Map<String, Object> m) {
        String url = m.get("notifyUrl").toString();
        String id = m.get("notifyId").toString();
        StringBuffer buffer = new StringBuffer();
        m.remove("notifyUrl");
        m.entrySet().forEach(s -> {
            buffer.append("&").append(s.getKey()).append("=").append(s.getValue());
        });
        String resultStr = HttpUtil.createPost(url).body(buffer.toString()).timeout((int) GlobalConstant.TIMEOUT).execute().body();
        NotifyRefundLogDO t = notifyRefundLogService.selectById(id);
        if (!"success".equals(resultStr)) {
            //通过插入数据库记录通知出错的记录
            if (Objects.nonNull(t)) {
                NotifyRefundLogDO logDO = NotifyRefundLogDO.builder()
                        .id(new BigInteger(id)).build();
                if (logDO.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) {
                    logDO.setStatus(PayNotifyStatusEnum.FAILURE.getStatus());
                } else {
                    logDO.setNotifyTimes(t.getNotifyTimes() + 1);
                }
                notifyRefundLogService.updateById(logDO);
            }
        } else {
            //通知成功处理
            NotifyRefundLogDO logDO = NotifyRefundLogDO.builder().status(PayNotifyStatusEnum.SUCCESS.getStatus())
                    .id(new BigInteger(id)).notifyTimes(t.getNotifyTimes() + 1)
                    .status(PayNotifyStatusEnum.SUCCESS.getStatus()).build();
            notifyRefundLogService.updateById(logDO);
        }
    }



}
